{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 导入数据集"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:40:44.662638200Z",
     "start_time": "2023-12-06T07:40:44.641652Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "303\n"
     ]
    },
    {
     "data": {
      "text/plain": "age           int64\nsex           int64\ncp            int64\ntrestbps      int64\nchol          int64\nfbs           int64\nrestecg       int64\nthalach       int64\nexang         int64\noldpeak     float64\nslope         int64\nca            int64\nthal         object\ntarget        int64\ndtype: object"
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(\"F:/机器学习数据集/心脏病预测/heart/heart.csv\")\n",
    "print(len(df))\n",
    "df.dtypes"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:40:45.374675400Z",
     "start_time": "2023-12-06T07:40:45.356667500Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "outputs": [
    {
     "data": {
      "text/plain": "0    220\n1     83\nName: target, dtype: int64"
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.target.value_counts()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:40:50.138848700Z",
     "start_time": "2023-12-06T07:40:50.115814600Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "data": {
      "text/plain": "age         0\nsex         0\ncp          0\ntrestbps    0\nchol        0\nfbs         0\nrestecg     0\nthalach     0\nexang       0\noldpeak     0\nslope       0\nca          0\nthal        0\ntarget      0\ndtype: int64"
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.isnull().sum()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:40:51.977849800Z",
     "start_time": "2023-12-06T07:40:51.948842400Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "outputs": [
    {
     "data": {
      "text/plain": "   age  sex  cp  trestbps  chol  fbs  restecg  thalach  exang  oldpeak  slope  \\\n0   63    1   1       145   233    1        2      150      0      2.3      3   \n1   67    1   4       160   286    0        2      108      1      1.5      2   \n2   67    1   4       120   229    0        2      129      1      2.6      2   \n3   37    1   3       130   250    0        0      187      0      3.5      3   \n4   41    0   2       130   204    0        2      172      0      1.4      1   \n\n   ca        thal  target  \n0   0       fixed       0  \n1   3      normal       1  \n2   2  reversible       0  \n3   0      normal       0  \n4   0      normal       0  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>age</th>\n      <th>sex</th>\n      <th>cp</th>\n      <th>trestbps</th>\n      <th>chol</th>\n      <th>fbs</th>\n      <th>restecg</th>\n      <th>thalach</th>\n      <th>exang</th>\n      <th>oldpeak</th>\n      <th>slope</th>\n      <th>ca</th>\n      <th>thal</th>\n      <th>target</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>63</td>\n      <td>1</td>\n      <td>1</td>\n      <td>145</td>\n      <td>233</td>\n      <td>1</td>\n      <td>2</td>\n      <td>150</td>\n      <td>0</td>\n      <td>2.3</td>\n      <td>3</td>\n      <td>0</td>\n      <td>fixed</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>67</td>\n      <td>1</td>\n      <td>4</td>\n      <td>160</td>\n      <td>286</td>\n      <td>0</td>\n      <td>2</td>\n      <td>108</td>\n      <td>1</td>\n      <td>1.5</td>\n      <td>2</td>\n      <td>3</td>\n      <td>normal</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>67</td>\n      <td>1</td>\n      <td>4</td>\n      <td>120</td>\n      <td>229</td>\n      <td>0</td>\n      <td>2</td>\n      <td>129</td>\n      <td>1</td>\n      <td>2.6</td>\n      <td>2</td>\n      <td>2</td>\n      <td>reversible</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>37</td>\n      <td>1</td>\n      <td>3</td>\n      <td>130</td>\n      <td>250</td>\n      <td>0</td>\n      <td>0</td>\n      <td>187</td>\n      <td>0</td>\n      <td>3.5</td>\n      <td>3</td>\n      <td>0</td>\n      <td>normal</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>41</td>\n      <td>0</td>\n      <td>2</td>\n      <td>130</td>\n      <td>204</td>\n      <td>0</td>\n      <td>2</td>\n      <td>172</td>\n      <td>0</td>\n      <td>1.4</td>\n      <td>1</td>\n      <td>0</td>\n      <td>normal</td>\n      <td>0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:40:53.660846600Z",
     "start_time": "2023-12-06T07:40:53.617826500Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "outputs": [
    {
     "data": {
      "text/plain": "sex        2\ncp         5\nfbs        2\nrestecg    3\nexang      2\nslope      3\nca         4\nthal       5\ndtype: int64"
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "categorical = ['sex','cp','fbs','restecg','exang','slope','ca','thal']\n",
    "numerical = ['age','trestbps','chol','thalach','oldpeak']\n",
    "df[categorical].nunique()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:40:59.430811900Z",
     "start_time": "2023-12-06T07:40:59.398824900Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "outputs": [
    {
     "data": {
      "text/plain": "age           int64\nsex          object\ncp           object\ntrestbps      int64\nchol          int64\nfbs          object\nrestecg      object\nthalach       int64\nexang        object\noldpeak     float64\nslope        object\nca           object\nthal         object\ntarget        int64\ndtype: object"
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for col in categorical:\n",
    "    df[col]=df[col].astype(object)\n",
    "df.dtypes"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:41:04.421270Z",
     "start_time": "2023-12-06T07:41:04.407244600Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 区分特征与目标"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    0\n",
      "1    1\n",
      "2    0\n",
      "3    0\n",
      "4    0\n",
      "Name: target, dtype: int64\n"
     ]
    },
    {
     "data": {
      "text/plain": "   age sex cp  trestbps  chol fbs restecg  thalach exang  oldpeak slope ca  \\\n0   63   1  1       145   233   1       2      150     0      2.3     3  0   \n1   67   1  4       160   286   0       2      108     1      1.5     2  3   \n2   67   1  4       120   229   0       2      129     1      2.6     2  2   \n3   37   1  3       130   250   0       0      187     0      3.5     3  0   \n4   41   0  2       130   204   0       2      172     0      1.4     1  0   \n\n         thal  \n0       fixed  \n1      normal  \n2  reversible  \n3      normal  \n4      normal  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>age</th>\n      <th>sex</th>\n      <th>cp</th>\n      <th>trestbps</th>\n      <th>chol</th>\n      <th>fbs</th>\n      <th>restecg</th>\n      <th>thalach</th>\n      <th>exang</th>\n      <th>oldpeak</th>\n      <th>slope</th>\n      <th>ca</th>\n      <th>thal</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>63</td>\n      <td>1</td>\n      <td>1</td>\n      <td>145</td>\n      <td>233</td>\n      <td>1</td>\n      <td>2</td>\n      <td>150</td>\n      <td>0</td>\n      <td>2.3</td>\n      <td>3</td>\n      <td>0</td>\n      <td>fixed</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>67</td>\n      <td>1</td>\n      <td>4</td>\n      <td>160</td>\n      <td>286</td>\n      <td>0</td>\n      <td>2</td>\n      <td>108</td>\n      <td>1</td>\n      <td>1.5</td>\n      <td>2</td>\n      <td>3</td>\n      <td>normal</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>67</td>\n      <td>1</td>\n      <td>4</td>\n      <td>120</td>\n      <td>229</td>\n      <td>0</td>\n      <td>2</td>\n      <td>129</td>\n      <td>1</td>\n      <td>2.6</td>\n      <td>2</td>\n      <td>2</td>\n      <td>reversible</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>37</td>\n      <td>1</td>\n      <td>3</td>\n      <td>130</td>\n      <td>250</td>\n      <td>0</td>\n      <td>0</td>\n      <td>187</td>\n      <td>0</td>\n      <td>3.5</td>\n      <td>3</td>\n      <td>0</td>\n      <td>normal</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>41</td>\n      <td>0</td>\n      <td>2</td>\n      <td>130</td>\n      <td>204</td>\n      <td>0</td>\n      <td>2</td>\n      <td>172</td>\n      <td>0</td>\n      <td>1.4</td>\n      <td>1</td>\n      <td>0</td>\n      <td>normal</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = df.target\n",
    "del df['target']\n",
    "print(y.head())\n",
    "df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:43:46.296250500Z",
     "start_time": "2023-12-06T07:43:46.224276700Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 计算互信息与相关系数"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "outputs": [
    {
     "data": {
      "text/plain": "               MI\nthal     0.116177\nca       0.114616\ncp       0.108108\nslope    0.078214\nexang    0.062691\nsex      0.015654\nrestecg  0.008695\nfbs      0.004484",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>MI</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>thal</th>\n      <td>0.116177</td>\n    </tr>\n    <tr>\n      <th>ca</th>\n      <td>0.114616</td>\n    </tr>\n    <tr>\n      <th>cp</th>\n      <td>0.108108</td>\n    </tr>\n    <tr>\n      <th>slope</th>\n      <td>0.078214</td>\n    </tr>\n    <tr>\n      <th>exang</th>\n      <td>0.062691</td>\n    </tr>\n    <tr>\n      <th>sex</th>\n      <td>0.015654</td>\n    </tr>\n    <tr>\n      <th>restecg</th>\n      <td>0.008695</td>\n    </tr>\n    <tr>\n      <th>fbs</th>\n      <td>0.004484</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import mutual_info_score\n",
    "def calculate_mi(series): # 创建计算互信息的独立函数\n",
    "    return mutual_info_score(series,y) # 使用sklearn中的互信息函数\n",
    "df_mi = df[categorical].apply(calculate_mi) # 将函数应用到每一个列\n",
    "df_mi = df_mi.sort_values(ascending=False).to_frame(name='MI')\n",
    "df_mi"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:45:14.451960100Z",
     "start_time": "2023-12-06T07:45:14.416966100Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "outputs": [
    {
     "data": {
      "text/plain": "age         0.198701\ntrestbps    0.129389\nchol        0.083327\nthalach    -0.386459\noldpeak     0.475324\ndtype: float64"
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[numerical].corrwith(y) # 相关系数"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:45:36.785002500Z",
     "start_time": "2023-12-06T07:45:36.764008500Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 划分独热编码"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "outputs": [
    {
     "data": {
      "text/plain": "array([ 63. ,   0. , 233. ,   1. ,   0. ,   1. ,   2.3,   2. ,   1. ,\n         3. ,   0. ,   0. ,   1. ,   0. ,   0. , 150. , 145. ])"
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.feature_extraction import DictVectorizer\n",
    "dv = DictVectorizer(sparse=False)\n",
    "df_dict = df.to_dict(orient='records')\n",
    "dv.fit(df_dict)\n",
    "X=dv.transform(df_dict)\n",
    "X[0]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:48:03.292999700Z",
     "start_time": "2023-12-06T07:48:03.235963700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "outputs": [
    {
     "data": {
      "text/plain": "['age',\n 'ca',\n 'chol',\n 'cp',\n 'exang',\n 'fbs',\n 'oldpeak',\n 'restecg',\n 'sex',\n 'slope',\n 'thal=1',\n 'thal=2',\n 'thal=fixed',\n 'thal=normal',\n 'thal=reversible',\n 'thalach',\n 'trestbps']"
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dv.get_feature_names()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T07:49:04.980820600Z",
     "start_time": "2023-12-06T07:49:04.964837600Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 模型预测"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测试集精度:85.526%\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)\n",
    "scaler = StandardScaler()\n",
    "scaler.fit(X_train)\n",
    "X_train_scaled =scaler.transform(X_train)\n",
    "X_test_scaled = scaler.transform(X_test)\n",
    "lr = LogisticRegression(random_state=1)\n",
    "lr.fit(X_train_scaled,y_train)\n",
    "print('测试集精度:{:.3f}%'.format(lr.score(X_test_scaled,y_test)*100))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T08:06:28.458103600Z",
     "start_time": "2023-12-06T08:06:28.443107500Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 删除一些特征"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'cp': 4, 'exang': 1, 'slope': 2, 'thal': 'normal', 'ca': 3, 'age': 67, 'trestbps': 160, 'thalach': 108, 'oldpeak': 1.5, 'chol': 286}\n",
      "测试集精度:86.842%\n"
     ]
    }
   ],
   "source": [
    "categorical = ['cp','exang','slope','thal','ca']\n",
    "numerical = ['age','trestbps','thalach','oldpeak','chol']\n",
    "df_drop = df[categorical+numerical]\n",
    "df_drop_dict = df_drop.to_dict(orient='records')\n",
    "print(df_drop_dict[1])\n",
    "dv_drop = DictVectorizer(sparse=False)\n",
    "dv_drop.fit(df_drop_dict)\n",
    "X_drop = dv_drop.transform(df_drop_dict)\n",
    "\n",
    "X_train,X_test,y_train,y_test = train_test_split(X_drop,y,random_state=0)\n",
    "scaler = StandardScaler()\n",
    "scaler.fit(X_train)\n",
    "X_train_scaled =scaler.transform(X_train)\n",
    "X_test_scaled = scaler.transform(X_test)\n",
    "lr = LogisticRegression(random_state=1)\n",
    "lr.fit(X_train_scaled,y_train)\n",
    "print('测试集精度:{:.3f}%'.format(lr.score(X_test_scaled,y_test)*100))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-06T08:38:09.681789500Z",
     "start_time": "2023-12-06T08:38:09.650821Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
